﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Design.Serialization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Foxit.PDF;
using Foxit.PDF.IO;
using Foxit.PDF.PageElements;

namespace Sustainalytics.ReportGenerator.BL
{
    public class SustainabilityAndBusinessImpactChart : PageElement
    {
        public float Left { get; set; }
        public float Top { get; set; }
        public float Width { get; set; }
        public float Height { get; set; }
        public List<KeyEsgIssueTemplate> KeyEsgIssueTemplates { get; set; }
        public List<KeyEsgIssue> KeyEsgIssues { get; set; }

        public SustainabilityAndBusinessImpactChart(float left, float top, float width, float height)
        {
            Left = left;
            Top = top;
            Width = width;
            Height = height;
        }

        private Group Chart()
        {
            var group = new Group();


            var left = Left + 20f;
            var lineSize = 1f;
            var lineColor = RgbColor.Black;

            const float rowCount = 10f;
            const float colCount = 10f;
            const int cellWidth = 35;
            const float cellHeight = 11.5f;

            const float verticalLineHeight = cellHeight * colCount;

            for (var i = 0; i <= rowCount; i++)
            {
                if (i > 0)
                {
                    lineSize = 0.2f;
                    lineColor = RgbColor.WhiteSmoke;
                }
                if (i == 3 || i == 7)
                {
                    lineSize = 0.2f;
                    lineColor = RgbColor.Silver;
                }
                group.Add(new Line(left, Top, left, Top + verticalLineHeight, lineSize, lineColor));
                left += cellWidth;
            }

            left = Left + 10f;
            var labelSize = 8f;

            group.Add(
                new Label("High", left, Top + cellHeight * 3, cellHeight * 3, 
                    labelSize + 2f, Fonts.CalibriBold, labelSize, 
                    TextAlign.Center, RgbColor.Black) { Angle = -90 });
            group.Add(
                new Label("Madium", left, Top + cellHeight * 7, cellHeight * 4, 
                    labelSize + 2f, Fonts.CalibriBold, labelSize, 
                    TextAlign.Center, RgbColor.Black) { Angle = -90 });
            group.Add(
                new Label("Low", left, Top + cellHeight * 10, cellHeight * 3,
                    labelSize + 2f, Fonts.CalibriBold, labelSize, 
                    TextAlign.Center, RgbColor.Black) { Angle = -90 });


            left = Left + 20f;
            var top = Top + cellHeight * rowCount;
            var leftOffset = 0.0f;

            const float horizontalLineHeight = cellWidth * colCount;
            lineSize = 1f;
            lineColor = RgbColor.Black;

            for (var i = 0; i < 11; i++)
            {
                if (i == 0)
                {
                    group.Add(
                        new Line(left + leftOffset, top, left + horizontalLineHeight, top, lineSize, lineColor));
                }
                if (i > 0)
                {
                    lineSize = 0.2f;
                    lineColor = RgbColor.WhiteSmoke;
                    leftOffset = 0.5f;
                    group.Add(
                        new Line(left + leftOffset, top, left + horizontalLineHeight - leftOffset, top, lineSize, lineColor));
                }
                if (i == 3 || i == 7)
                {
                    lineColor = RgbColor.Silver;
                    group.Add(
                        new Line(left + leftOffset, top, left + horizontalLineHeight - leftOffset, top, lineSize, lineColor));
                }
                
                top -= cellHeight;
            }
            

            top = Top + cellHeight*rowCount + 5f;

            group.Add(
                new Label("Low", left, top, cellWidth * 3, 
                    labelSize + 2f, Fonts.CalibriBold, labelSize, TextAlign.Center));
            group.Add(
                new Label("Madium", left + cellWidth * 3, top, cellWidth * 4, 
                    labelSize + 2f, Fonts.CalibriBold, labelSize, TextAlign.Center));
            group.Add(
                new Label("High", left + cellWidth * 7, top, cellWidth * 3, 
                    labelSize + 2f, Fonts.CalibriBold, labelSize, TextAlign.Center));

            left = Left + 20f;
            top = Top + cellHeight * rowCount + 15f;
            labelSize = 10f;

            group.Add(
                new Label("Sustainability Impact", Left, Top + cellHeight * 10, cellHeight * 10,
                    labelSize + 2f, Fonts.CalibriBold, labelSize, 
                    TextAlign.Center, RgbColor.Black) { Angle = -90 });

            group.Add(
                new Label("Business Impact", left, top, cellWidth * 10,
                    labelSize + 2f, Fonts.CalibriBold, labelSize,
                    TextAlign.Center, RgbColor.Black));

            RgbColor pointColor;

            for (var sImpact = 0; sImpact < 10; sImpact++)
            {
                for (var bImpact = 0; bImpact < 10; bImpact++)
                {
                    pointColor = RgbColor.DimGray;


                    var keyEsgIssue = KeyEsgIssues.SingleOrDefault(kei => kei.SustainabilityImpact - 1 == sImpact
                                                                       && kei.BussinessImpact - 1 == bImpact);

                    var keyEsgIssueTemplate = KeyEsgIssueTemplates.SingleOrDefault(keit => keyEsgIssue != null && keit.Name == keyEsgIssue.Name);

                    if (keyEsgIssue == null || keyEsgIssueTemplate == null) continue;
                    
                    pointColor = RgbColor.Turquoise;


                    left = Left + 20 + (bImpact*cellWidth) + (cellWidth/2);
                    top = Top + cellHeight*10 - (sImpact*cellHeight) - (cellHeight/2);

                    @group.Add(
                        new Circle(left, top, 4f, 4f, pointColor, pointColor, 0.5f, LineStyle.Solid));
                    @group.Add(
                        new Label(keyEsgIssueTemplate.Code, left - 4f, top - 4f, 8f,
                            7f, Fonts.CalibriBold, 7f,
                            TextAlign.Center, RgbColor.White));
                }
            }

            //group.Add(new Rectangle(Left, Top, Width, Height, RgbColor.Blue,
            //    RgbColor.White, 0.5f, LineStyle.Dash));


            left = Left + 20 + (10f * cellWidth) + 30f;
            top = Top;
            labelSize = 8;
 
            foreach (var keyESGIssueTempate in KeyEsgIssueTemplates)
            {
                
                group.Add(
                    new Circle(left + 4, top + 4f, 4f, 4f, RgbColor.DimGray, RgbColor.DimGray, 0.5f, LineStyle.Solid));
                group.Add(
                    new Label(keyESGIssueTempate.Code, left, top + 0.5f, 8f,
                        labelSize + 2f, Fonts.CalibriBold, labelSize,
                        TextAlign.Center, RgbColor.White));
                group.Add(
                    new Label(keyESGIssueTempate.Name, left + 20f, top, 200f,
                        labelSize + 2f, Fonts.CalibriBold, labelSize,
                        TextAlign.Left, RgbColor.Black));
                top += 15;
            }

            return group;
        }

        public override void Draw(PageWriter writer)
        {
            var chart = Chart();

            writer.Write_q_(true);
            chart.Draw(writer);
            writer.Write_Q(true);
        }
    }
}
